export class LoadedPromiseWrapper<T = any> {
  request?: () => Promise<T>
  promise?: Promise<T>
  loadedStatus?: 'LOADED'
  cbs: Array<(result: T) => void>
  result: T | null
  constructor(request?: () => Promise<T>) {
    this.request = request
    this.cbs = []
    this.result = null
  }
  execute() {
    this.cbs.forEach((cb) => {
      cb && cb(this.result!)
    })
  }
  async trigger(result: T) {
    this.loadedStatus = undefined
    this.result = result
    if (this.request) {
      this.promise = this.request()
      if (result) {
        this.result = result
      } else {
        this.result = await this.promise
      }
    }
    this.loadedStatus = 'LOADED'
    this.execute()
  }
  _loadedPromise(cb: (result: T) => void) {
    if (this.loadedStatus !== 'LOADED') {
      this.cbs.push(cb)
    } else {
      cb(this.result!)
    }
  }
  loadedPromise(cb?: (params: T) => any): Promise<T> {
    return new Promise((resolve) => {
      this._loadedPromise((result: T) => {
        cb && cb(result)
        resolve(result)
      })
    })
  }

  reset() {
    this.promise = undefined
    this.loadedStatus = undefined
    this.cbs = []
    this.result = null
  }
}
